// Test sending and receiving data from OSC, by connecting with the Arduino server (Arduino_ServerAlvaro)
 
import oscP5.*;
import netP5.*;
  
OscP5 oscP5;
NetAddress myRemoteLocation;

int currentControlledSpot=0; // this is the identifier for the controlling the spot. Change it with keys 0 to 2
int thresholdMode=0;

color[] colorTable={color(255,0,0), color(0,255,0), color(0,0,255), color(0,255,255)};

int numSpots=4;
spot[] spotArray=new spot[numSpots];

// special "spot" for displaying image:
spot pixelScan;

int MIRRORS_MAX=4000; // 2000 is the center of the display
int xMax = 3650, xMin = 350, yMax = 3650, yMin = 350;

boolean scanningImage=false;

PFont myFont;

void setup() {
  size(800, 800);
  
  myFont = loadFont("ArialMT-20.vlw");
  textAlign(CENTER);
  textFont(myFont, 20);
  
  frameRate(6000);
  /* start oscP5, listening for incoming messages at port 12000 */
  oscP5 = new OscP5(this,12000);
  
  /* myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
   * an ip address and a port number. myRemoteLocation is used as parameter in
   * oscP5.send() when sending osc packets to another computer, device, 
   * application. usage see below. for testing purposes the listening port
   * and the port of the remote location address are the same, hence you will
   * send messages back to this sketch.
   */
  myRemoteLocation = new NetAddress("10.0.0.2",10000); // sending to port 10000
  
   for (int i=0; i<numSpots; i++) {
    spotArray[i]=new spot(i, colorTable[i]);
  }
  
  pixelScan=new spot(-1, color(0,0,0));
  
   // graphic properties: 
  smooth();  // smooth stroke
  ellipseMode(CENTER_RADIUS); 
}


void draw() {

  if (!scanningImage)  background(0); 
  //     fill(8,10);
  //  rect(0,0,width, height);
 
 noFill(); stroke(0,255,0); rectMode(CORNER);
 rect(1.0*xMin/4000*width, 1.0*yMin/4000*height,1.0*(xMax-xMin)/4000*width, 1.0*(yMax-yMin)/4000*height);
  
  if (!scanningImage) {
  for (int i=0; i<numSpots; i++) {
    spotArray[i].display();
    // indicate current spot under control:
    if (currentControlledSpot==i) {
      fill(255); noStroke();
      ellipse( spotArray[i].x, spotArray[i].y,3,3);
    }
  }
  } else { 
    pixelScan.displayPixel();
  }
  
}

/*
void mouseDragged() {
  // in the following different ways of creating osc messages are shown by example
  OscMessage myMessage = new OscMessage("/setMirrors");// /setMirrors"); // subaddresses just by doing: /top/sub
  
  myMessage.add((int)(1.0*mouseX/width*4096)); // add an int to the osc message 
  myMessage.add((int)(1.0*mouseY/height*4096)); // add an int to the osc message 

  // send the message 
  oscP5.send(myMessage, myRemoteLocation); 
}
*/


/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
  // MESSY!!!!!
   String alladdress=theOscMessage.addrPattern();
   
  if (alladdress.equals("/scan/pos")) {
   // print("here");
     pixelScan.x = theOscMessage.get(0).intValue(); 
     pixelScan.y =  theOscMessage.get(1).intValue(); 
  } 
  else if (alladdress.equals("/scan/value")) {
    int intensity=theOscMessage.get(0).intValue(); // form 0 to 255
    pixelScan.myColor=color(intensity); 
  }
  
  else if (theOscMessage.checkTypetag("ii")) {
      //String alladdress=theOscMessage.addrPattern();
    //  println(alladdress);
    for (int i=0; i<numSpots; i++) {
     if (alladdress.equals(i+"/pos")){  // or topaddress.equals("spot"+i+"/pos") is using spot names as "spot1", "spot2"...
  spotArray[i].x = 1.0*width/4095*theOscMessage.get(0).intValue(); 
  spotArray[i].y =  1.0*height/4095*theOscMessage.get(1).intValue(); 
  //println(" x="+x+", y="+y);
    } else if (alladdress.equals(i+"/maxmin")){
    spotArray[i].maxInt = theOscMessage.get(0).intValue(); 
    spotArray[i].minInt = theOscMessage.get(1).intValue(); 
    //print(alladdress+" "+str(theOscMessage.get(0).intValue()));
   }
 }
}
}

void keyPressed() {

if ((key>=48)&&(key<=48+numSpots-1)) currentControlledSpot=key-48;
  
   // GLOBAL COMMANDS:
 else if (key=='r') { // reset all spots (all dead, and parameters reinitialized)
  OscMessage myMessage = new OscMessage("/resetAll");
   oscP5.send(myMessage, myRemoteLocation); 
} 

// demo modes:
else if (key=='g') { 
  OscMessage myMessage = new OscMessage("/oneContourFollowing");
   oscP5.send(myMessage, myRemoteLocation); 
} 
else if (key=='h') { 
  OscMessage myMessage = new OscMessage("/twoSimpleBouncing");
   oscP5.send(myMessage, myRemoteLocation); 
} 
else if (key=='j') { 
  OscMessage myMessage = new OscMessage("/oneSnellLaw");
   oscP5.send(myMessage, myRemoteLocation); 
} 


// PER-SPOT COMMAND:
else if (key=='a') { // set spot 0 alive
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/resucite"); // or "/spot1"...
  oscP5.send(myMessage, myRemoteLocation); 
} 
else if (key=='d') { // set spot 0 dead
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/kill");
  oscP5.send(myMessage, myRemoteLocation); 
}

// modes:
else if (key==' ') { // standby
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/standBy");
  oscP5.send(myMessage, myRemoteLocation); 
}  
else if (key=='f') { // standby
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/contourFollowing");
  oscP5.send(myMessage, myRemoteLocation); 
}  
else if (key=='g') { // standby
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/simpleBouncing");
  oscP5.send(myMessage, myRemoteLocation); 
}  
else if (key=='h') { // standby
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/snellLaw");
  oscP5.send(myMessage, myRemoteLocation); 
}  

else if (key=='o') { // set OSC mode ON
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendOSC");
   myMessage.add(1);
   oscP5.send(myMessage, myRemoteLocation); 
} 
else if (key=='O') { // set OSC mode OFF
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendOSC");
   myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 

else if (key=='s') { // set Serial mode ON
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendSerial");
   myMessage.add(1);
   oscP5.send(myMessage, myRemoteLocation); 
} 
else if (key=='S') { // set Serial mode OFF
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendSerial");
   myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 

else if (key=='p') { // set position send to ON
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendingPosition");
   myMessage.add(1);
   oscP5.send(myMessage, myRemoteLocation); 
}  
  else if (key=='P') { // set position send to OFF
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendingPosition");
   myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 

else if (key=='c') { // set color send to ON
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendingColor");
   myMessage.add(1);
   oscP5.send(myMessage, myRemoteLocation); 
}  
  else if (key=='C') { // set color send to OFF
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/sendingColor");
   myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 


 else if (keyCode==UP) { //speed up
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/speedUp");
  // myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 
 else if (keyCode==DOWN) { //slow down
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/slowDown");
  // myMessage.add(0);
   oscP5.send(myMessage, myRemoteLocation); 
} 

 else if (keyCode==TAB) { //change threshold mode for the current spot
  OscMessage myMessage = new OscMessage("/"+str(currentControlledSpot)+"/setThresholdMode");
  thresholdMode=1-thresholdMode;
  myMessage.add((long)thresholdMode);
   oscP5.send(myMessage, myRemoteLocation); 
} 

 else if (keyCode==ENTER) { //change threshold mode for the current spot
   scanningImage=!scanningImage;
   if (scanningImage) {
   OscMessage myMessage = new OscMessage("/takeSnapshot");
   oscP5.send(myMessage, myRemoteLocation); 
   }
} 


}

